﻿/*
Copyright (c) 2010 Lance Ward
This software is licensed under the MIT license, except where otherwise noted.
For complete license details, refer to license.txt
*/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ADNColorPicker
{
	public partial class PaletteBox : UserControl
	{
		private List<PalColor> colors = new List<PalColor>();
		private Bitmap palBitmap;
		const int palSize = 15;
		private int selectedColor = -1;

		public PaletteBox()
		{
			InitializeComponent();
			LoadColors();
			CreatePalette();
		}

		public event EventHandler ColorChanged;
		protected virtual void OnColorChanged()
		{
            if (ColorChanged != null)
			{
                ColorChanged(this, EventArgs.Empty);
			}
		}

		public Color SelectedColor
		{
			get
			{
				if (selectedColor >= 0) { return colors[selectedColor].ToColor(); }
				else { return Color.Transparent; }
			}
		}

		private void LoadColors()
		{
			//look for default.adnp

			for (int i = 0; i < 17; i++)
			{
				PalColor p = new PalColor(Color.Black.A, Color.Black.R, Color.Black.G, Color.Black.B);
				colors.Add(p);

				p = new PalColor(Color.Blue.A, Color.Blue.R, Color.Blue.G, Color.Blue.B);
				colors.Add(p);

				p = new PalColor(Color.Red.A, Color.Red.R, Color.Red.G, Color.Red.B);
				colors.Add(p);

				p = new PalColor(Color.Green.A, Color.Green.R, Color.Green.G, Color.Green.B);
				colors.Add(p);

				p = new PalColor(Color.Yellow.A, Color.Yellow.R, Color.Yellow.G, Color.Yellow.B);
				colors.Add(p);

				p = new PalColor(Color.Orange.A, Color.Orange.R, Color.Orange.G, Color.Orange.B);
				colors.Add(p);

				p = new PalColor(Color.Purple.A, Color.Purple.R, Color.Purple.G, Color.Purple.B);
				colors.Add(p);

				p = new PalColor(Color.BlueViolet.A, Color.BlueViolet.R, Color.BlueViolet.G, Color.BlueViolet.B);
				colors.Add(p);

				p = new PalColor(Color.Aqua.A, Color.Aqua.R, Color.Aqua.G, Color.Aqua.B);
				colors.Add(p);

				p = new PalColor(Color.Firebrick.A, Color.Firebrick.R, Color.Firebrick.G, Color.Firebrick.B);
				colors.Add(p);
			}
		}

		private void CreatePalette()
		{
			palBitmap = new Bitmap(this.Width, this.Height);
			Graphics g = Graphics.FromImage(palBitmap);
	
			int currX = 1;
			int currY = 1;

			for (int i = 0; i < colors.Count; i++)
			{
				Brush b = new SolidBrush(Color.FromArgb(colors[i].A, colors[i].R, colors[i].G, colors[i].B));
				g.FillRectangle(b, currX, currY, palSize, palSize);

				currX += palSize + 1; //pixel spacer

				if (currX >= palBitmap.Width)
				{
					currY += palSize + 1;
					currX = 1;
				}
			}

		}

        private void PaletteBox_MouseClick(object sender, MouseEventArgs e)
		{
			Color pixel = palBitmap.GetPixel(e.X, e.Y);
			selectedColor = GetCellIndex(e.Location);
            OnColorChanged();
			this.Invalidate();
		}

		private int GetCellIndex(Point location)
		{
			int col = (location.X / (palSize + 1)) + 1;
			int row = (location.Y / (palSize + 1)) + 1;
			int maxXCells = (this.ClientRectangle.Width - 1) / (palSize + 1);
			//row -1 X maxPerRow + col;
			return ((row -1) * maxXCells) + col - 1;
		}

		private Rectangle GetIndexRect(int index)
		{
			int maxXCells = (this.ClientRectangle.Width - 1)/(palSize + 1);
			
			Rectangle rect = new Rectangle();
			rect.Width = palSize;
			rect.Height = palSize;
			rect.Y = (int)(Math.Floor((double)(index) / maxXCells) * (palSize + 1)) + 1;
			rect.X = (int)(((index) % maxXCells) * (palSize + 1)) + 1; 

			return rect;
		}

        private void PaletteBox_MouseDown(object sender, MouseEventArgs e)
		{
			//draw selection square
		}

        private void PaletteBox_MouseMove(object sender, MouseEventArgs e)
		{
			//move the selected color
		}

        private void PaletteBox_MouseUp(object sender, MouseEventArgs e)
		{
			//delete and insert the selected color
			//redraw the image
		}

        private void PaletteBox_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawImage(palBitmap, 0, 0);
			if (selectedColor >= 0) { e.Graphics.DrawRectangle(new Pen(Color.Blue, 2.0f), GetIndexRect(selectedColor)); }
        }

        private void PaletteBox_Resize(object sender, EventArgs e)
        {
            CreatePalette();
        }

		private void PaletteBox_MouseLeave(object sender, EventArgs e)
		{

		}
	}
}
